/**
 * Basic pseudo-logger mock-up.
 *
 * @author Jorge Hernandez
 */
class org.molamil.acto.core.Logger {

	
	// Constants
	
	/**
	 * Name for the default logger, used with <code>getLogger()</code> with no params. 
	 * With value <code>APP</code>
	 */
	public static function get DEFAULT_LOGGER_NAME():String { return "APP"; }
	
	/**
	 * Off level - no logging. 
	 * With value <code>0</code>
	 */
	public static function get LEVEL_OFF():Number { return 0; }
	
	/**
	 * Severe level. 
	 * With value <code>1</code>
	 */
	public static function get LEVEL_SEVERE():Number { return 1; }
	
	/**
	 * Warning level. 
	 * With value <code>2</code>
	 */
	public static function get LEVEL_WARNING():Number { return 2; }
	
	/**
	 * Info level. 
	 * With value <code>3</code>
	 */
	public static function get LEVEL_INFO():Number { return 3; }
	
	/**
	 * Debug level. 
	 * With value <code>4</code>
	 */
	public static function get LEVEL_DEBUG():Number { return 4; }
	
	private static var LEVEL_LABELS:Array = ["", "SEVERE", "WARNING", "INFO", "DEBUG"];
	
	
	// Properties
	
	/**
	 * Current log level - 1 to 4, DEBUG to SEVERE.
	 */
	public static var level:Number = LEVEL_WARNING;
	
	private static var loggers:Object = new Object();
	
	private var name:String;
	
	
	// Constructor
	
	private function Logger() {}
	
	
	// Functions
	
	/**
	 * Singleton method to get a <code>Logger</code>.
	 * 
	 * @return  Logger instance.
	 */
	public static function getLogger(name:String):Logger {
		
		var instance:Logger;
		
		// Create a default Logger if it's not there.
	    if (loggers[DEFAULT_LOGGER_NAME] == null) {
			loggers[DEFAULT_LOGGER_NAME] = new Logger();
			loggers[DEFAULT_LOGGER_NAME].name = DEFAULT_LOGGER_NAME;
		}
		
		// If there's no name, we return the default Logger.
		if (name == null) {
			instance = loggers[DEFAULT_LOGGER_NAME];
		} else {
			loggers[name] = new Logger();
			loggers[name].name = name;
			instance = loggers[name];
		}
		
		return instance;
		
	}
	
	public function debug(message:String):Void {
		log(LEVEL_DEBUG, message);
	}
	
	public function info(message:String):Void {
		log(LEVEL_INFO, message);
	}
	
	public function severe(message:String):Void {
		log(LEVEL_SEVERE, message);
	}
	
	public function warning(message:String):Void {
		log(LEVEL_WARNING, message);
	}
	
	private function log(level:Number, message:String):Void {
		if (Logger.level >= level) {
			var d:Date = new Date();
			var ds:String = d.getFullYear() 
				+ "-" + paddLeft("" + (d.getMonth() + 1), 2, "0")
				+ "-" + paddLeft("" + d.getDate(), 2, "0")
				+ " " + paddLeft("" + d.getHours(), 2, "0")
				+ ":" + paddLeft("" + d.getMinutes(), 2, "0")
				+ ":" + paddLeft("" + d.getSeconds(), 2, "0")
				+ ":" + paddLeft("" + d.getMilliseconds(), 2, "0");
			var s:String = paddRight(ds, 15)
				+ " - " + paddRight(LEVEL_LABELS[level], 7)
				+ " - " + paddRight(name, 24)
				+ " - " + message;
			trace(s);
		}
	}
	
	private function paddRight(s:String, l:Number, c:String):String {
		if (c == null)
			c = " ";
		while (s.length < l)
			s += c;
		return s;
	}
	
	private function paddLeft(s:String, l:Number, c:String):String {
		if (c == null)
			c = " ";
		while (s.length < l)
			s = c + s;
		return s;
	}
	  
	  
}